/**
 * 
 */
package com.module.hq.ui.mono.heroviewer.widgets;

import java.awt.Color;
import java.awt.Dimension;

import com.dalonedrau.jogl.engine.Action;
import com.dalonedrau.jogl.engine.GlobalConsts;
import com.dalonedrau.jogl.engine.InputEvent;
import com.dalonedrau.jogl.engine.Interface;
import com.dalonedrau.jogl.engine.JOGLErrorHandler;
import com.dalonedrau.jogl.opengl.ui.Button;
import com.dalonedrau.jogl.opengl.ui.UIFactory;
import com.dalonedrau.jogl.opengl.ui.panel.CardPanel;
import com.dalonedrau.jogl.opengl.ui.panel.Panel;
import com.dalonedrau.jogl.opengl.ui.panel.PortraitPagePanel;
import com.dalonedrau.vectors.Vector3;
import com.module.hq.engine.HQEquipment;
import com.module.hq.engine.HQInteractiveObject;
import com.module.hq.engine.HQInventory;
import com.module.hq.ui.mono.borders.HQMonoH1HighlightBorder;
import com.module.hq.ui.mono.borders.HQMonoTooltipBorder;

/**
 * @author Donald
 */
public final class EquipmentDialog extends PortraitPagePanel {
	/**
	 * the one and only instance of the <code>EquipmentDialog</code> class.
	 */
	private static EquipmentDialog	instance;
	/**
	 * Gives access to the singleton instance of {@link EquipmentDialog}.
	 * @return {@link EquipmentDialog}
	 */
	public static EquipmentDialog getInstance() {
		if (EquipmentDialog.instance == null) {
			EquipmentDialog.instance = new EquipmentDialog();
		}
		return EquipmentDialog.instance;
	}
	/** the drop button. */
	private Button		btnDrop;
	/** the equip button. */
	private Button		btnEquip;
	/** the unequip button. */
	private Button		btnUnequip;
	/** the equip/unequip button panel. */
	private CardPanel	pnlEquip;
	/** the equipment slot being interacted with. */
	private int			slot;
	/**
	 * Equips/unequips an item.
	 * @param equips if true, the item is equipped; otherwise the item is 
	 * unequipped
	 * @throws Exception if an error occurs
	 */
	public void equipItem(final boolean equips) throws Exception {
		HQInteractiveObject pio = HQInventory.getInstance().getPlayerViewed();
		HQInteractiveObject iio = 
			HQInventory.getInstance().getInventoryObject(pio, slot);
		if (equips) {
		HQEquipment.getInstance().equipItem(pio, iio);
		} else {
			HQEquipment.getInstance().unequip(pio, iio, false);
		}
		hideDialog();		
	}
	/**
	 * Creates a new instance of {@link EquipmentDialog}.
	 */
	public EquipmentDialog() {
		super(Panel.PORTRAIT_LEFT);
		final EquipmentDialog me = this;
		// initialize
		pnlEquip = new CardPanel();
		btnEquip = UIFactory.getInstance().getStandardH1Button("Equip  ");
		btnEquip.setHighlightable(true);
		btnEquip.setHighlightBorder(
				new HQMonoH1HighlightBorder(btnEquip.getId()));
		btnEquip.addAction(new Action() {
			/**
			 * {@inheritDoc}
			 */
			@Override
			public void performAction() {
				try {
					// add call to load barbarian stats
					InputEvent.getInstance().addAction(
							me, // object
							me.getClass().getMethod(
									"equipItem", new Class[] { boolean.class }),
							new Boolean[] { true }
							);
				} catch (Exception ex) {
					JOGLErrorHandler.getInstance().fatalError(ex);
				}
			}
		});
		pnlEquip.addChild("equip", btnEquip);
		
		btnUnequip = UIFactory.getInstance().getStandardH1Button("Unequip");
		btnUnequip.setHighlightable(true);
		btnUnequip.setHighlightBorder(
				new HQMonoH1HighlightBorder(btnEquip.getId()));
		btnUnequip.addAction(new Action() {
			/**
			 * {@inheritDoc}
			 */
			@Override
			public void performAction() {
				try {
					// add call to load barbarian stats
					InputEvent.getInstance().addAction(
							me, // object
							me.getClass().getMethod(
									"equipItem", new Class[] { boolean.class }),
							new Boolean[] { false }
							);
				} catch (Exception ex) {
					JOGLErrorHandler.getInstance().fatalError(ex);
				}
			}
		});
		pnlEquip.addChild("unequip", btnUnequip);
		super.addChild(pnlEquip);
		
		btnDrop = UIFactory.getInstance().getStandardH1Button("Drop");
		btnDrop.setHighlightable(true);
		btnDrop.setHighlightBorder(
				new HQMonoH1HighlightBorder(btnEquip.getId()));
		btnDrop.addAction(new Action() {
			/**
			 * {@inheritDoc}
			 */
			@Override
			public void performAction() {
				try {
					// add call to load barbarian stats
					InputEvent.getInstance().addAction(
							me, // object
							me.getClass().getMethod(
									"dropItem", null),
							null
							);
				} catch (Exception ex) {
					JOGLErrorHandler.getInstance().fatalError(ex);
				}
			}
		});
		super.addChild(btnDrop);
		super.setBorder(new HQMonoTooltipBorder());
	}
	/** Drops an item. */
	public void dropItem() {
		// add code to drop item
		hideDialog();
	}
	/** Hides the dialog. */
	public void hideDialog() {
		super.setVisible(false);
		super.setPosition(0, 0, 0);
		Interface.getInstance().removeViewFlag(
				GlobalConsts.VW_07_DLG_WINDOW);
	}
	/**
	 * Shows the dialog.
	 * @param s the inventory slot being interacted with
	 */
	public void showDialog(final int s) {
		try {
			slot = s;
			super.setPreferredSize(0, 0);
			super.setPosition(-GlobalConsts.INT_999, -GlobalConsts.INT_999, 
					-GlobalConsts.INT_999);
			switchButtons();
			// position the dialog
			Dimension d = getPreferredSize();
			// get parent size
			Dimension p = HQInventory.getInstance()
					.getPreferredSizeWhenDisplayingTooltip();
			// get parent position
			Vector3 parentPos =
					HQInventory.getInstance().getPreferredTooltipPosition();
			// figure out the best position
			if (parentPos != null) { // should never be null
				Vector3 newPos = new Vector3(parentPos);
				// move dialog so that top is at top of inv slot
				newPos.move(0, -d.height + p.height, GlobalConsts.INT_100);
				// move to right of inv slot
				newPos.move(p.width, 0, 0);				
				if (newPos.getX() + d.width < GlobalConsts.SCREEN_WIDTH) {
					// will fit left-right. will it fit up-down?
					if (newPos.getY() - d.height > 0) {
						// dialog will fit at this position. display it
						super.setPosition(
								newPos.getX(),
								newPos.getY(),
								newPos.getZ() + GlobalConsts.INT_999
								);
					} else {
						// dialog will not fit above window edge,
						// move back to bottom of inv slot
						newPos.move(0, +d.height - p.height, 0);
						super.setPosition(
								newPos.getX(),
								newPos.getY(),
								newPos.getZ() + GlobalConsts.INT_999
								);
					}
				} else {
					// won't fit left-right
					// dialog is right of inv slot. move to left of slot
					newPos.move(-p.width - d.width, 0, 0);
					// will fit left-right. will it fit up-down?
					if (newPos.getY() - d.height > 0) {
						super.setPosition(
								newPos.getX(),
								newPos.getY(),
								newPos.getZ() + GlobalConsts.INT_999
								);
					} else {
						// dialog will not fit above window edge,
						// move back to bottom of inv slot
						newPos.move(0, d.height - p.height, 0);
						super.setPosition(
								newPos.getX(),
								newPos.getY(),
								newPos.getZ() + GlobalConsts.INT_999
								);
					}
				}
			}
			super.setVisible(true);
			Interface.getInstance().assignViewFlag(
					GlobalConsts.VW_07_DLG_WINDOW);
		} catch (Exception ex) {
			JOGLErrorHandler.getInstance().fatalError(ex);
		}
	}
	/**
	 * Switches between displaying the EQUIP and UNEQUIP buttons, depending on
	 * the item.
	 * @throws Exception if an error occurs
	 */
	private void switchButtons() throws Exception {
		HQInteractiveObject pio =
				HQInventory.getInstance().getPlayerViewed();
		HQInteractiveObject iio =
				HQInventory.getInstance().getInventoryObject(pio, slot);
		// is player equipped with item?
		if (HQEquipment.getInstance().isPlayerEquippedWithItem(pio, iio)) {
			// player is equipped. show unequipped
			pnlEquip.displayChild("unequip");
		} else {
			// player is not equipped
			if (HQEquipment.getInstance().canEquipItem(pio, iio)) {
				btnEquip.setActive(true);
			} else {
				btnEquip.setActive(false);
			}
			pnlEquip.displayChild("equip");
		}
	}
}
